package gemini.castor.ui.client.page.content.home.register.inputaccount;

import gemini.castor.ui.client.constants.I18nConstants;
import gemini.castor.ui.client.page.widget.ErrorWidget;
import gemini.castor.ui.client.utils.GuiUtils;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.validation.client.InvalidConstraint;
import com.google.gwt.validation.client.interfaces.IValidator;

public class InputAccountFormView extends Composite implements
		InputAccountFormPresenter.Display {

	@UiTemplate("InputAccountFormView.ui.xml")
	interface MyUiBinder extends UiBinder<Panel, InputAccountFormView> {
	}

	private static final MyUiBinder binder = GWT.create(MyUiBinder.class);
	private IValidator<InputAccountFormObject> validator;
	private I18nConstants constants;

	public InputAccountFormView() {
		initWidget(binder.createAndBindUi(this));
		constants = GWT.create(I18nConstants.class);
		validator = GWT.create(InputAccountFormObject.class);
	}

	@UiField
	ErrorWidget htmRegisterError;
	
	@UiField
	HTML htmDistributorCode;
	
	@UiField
	HTML htmFullName;
	
	@UiField
	HTML htmSpouseFullName;
	
	@UiField
	HorizontalPanel pnlSpouseFullName;
	
	@UiField
	CheckBox chxAsCode;
	
	@UiHandler("chxAsCode")
	void onCheckAsCode(ClickEvent e) {
		checkAsCode();
	}
	
	private void checkAsCode(){
		tbxUsername.setEnabled(!chxAsCode.getValue());
		if (chxAsCode.getValue()) {
			tbxUsername.setValue(object.getDistributorCode());
		} else {
			tbxUsername.setValue("");
		}
	}
	
	@UiField
	CheckBox chxAsPin;
	
	@UiHandler("chxAsPin")
	void onCheckAsPin(ClickEvent e) {
		checkAsPin();
	}
	
	private void checkAsPin(){
		tbxPassword.setEnabled(!chxAsPin.getValue());
		tbxRetypePassword.setEnabled(!chxAsPin.getValue());
		if (chxAsPin.getValue()) {
			tbxPassword.setValue(object.getDistributorPin());
			tbxRetypePassword.setValue(object.getDistributorPin());
		} else {
			tbxPassword.setValue("");
			tbxRetypePassword.setValue("");
		}
	}
	
	@UiField
	CheckBox chxAsEmail;
	
	@UiHandler("chxAsEmail")
	void onCheckAsEmail(ClickEvent e) {
		checkAsEmail();
	}
	
	private void checkAsEmail(){
		tbxEmail.setEnabled(!chxAsEmail.getValue());
		if (chxAsEmail.getValue()) {
			tbxEmail.setValue(object.getDistributorEmail());
		} else {
			tbxEmail.setValue("");
		}
	}
	
	@UiField
	CheckBox chxIAgree;
	
	@UiHandler("chxIAgree")
	void onCheckIAgree(ClickEvent e) {
		checkIAgree();
	}
	
	private void checkIAgree(){
		btnRegister.setEnabled(chxIAgree.getValue());
	}
	
	@UiField
	TextBox tbxUsername;
	
	@UiField
	TextBox tbxEmail;
	
	@UiField
	PasswordTextBox tbxPassword;
	
	@UiField
	PasswordTextBox tbxRetypePassword;
	
	@UiField
	ListBox lbxLanguage;
	
	@UiField
	Button btnRegister;
	
	@UiField
	Button btnReset;
	
	@UiHandler("btnReset")
	void onReset(ClickEvent e) {
		reset();
	}
	
	private void reset() {
		resetValue();
		resetStyle();
		
		htmRegisterError.setVisible(false);
		
		chxAsCode.setValue(false);
		checkAsCode();
		
		chxAsEmail.setValue(false);
		checkAsEmail();
		
		chxAsPin.setValue(false);
		checkAsPin();

		chxIAgree.setValue(false);
		checkIAgree();
	}
	
	private void resetValue() {
		lbxLanguage.setSelectedIndex(0);
	}
	
	private void resetStyle() {
		tbxEmail.removeStyleDependentName("error");
		tbxPassword.removeStyleDependentName("error");
		tbxRetypePassword.removeStyleDependentName("error");
		tbxUsername.removeStyleDependentName("error");
	}
	
	private void showError(String widgetName, String errorString) {
		if (widgetName.equals("email")) {
			tbxEmail.addStyleDependentName("error");
		}else if (widgetName.equals("pin")) {
			tbxPassword.addStyleDependentName("error");
		}else if (widgetName.equals("retypePin")) {
			tbxRetypePassword.addStyleDependentName("error");
		}else if (widgetName.equals("username")) {
			tbxUsername.addStyleDependentName("error");
		}
	}
	@Override
	public boolean isValidate() {
		resetStyle();
		bind();
		boolean result = true;
		Set<InvalidConstraint<InputAccountFormObject>> invalidConstraints = validator
				.validate(object);
		Iterator<InvalidConstraint<InputAccountFormObject>> it = invalidConstraints
				.iterator();

		while (it.hasNext()) {
			if (result){
				result = false;
			}
			InvalidConstraint<InputAccountFormObject> ic = it.next();
			showError(ic.getItemName(), ic.getMessage());
		}
		if (!result) {
			htmRegisterError.setVisible(true);
		}
		return result;
	}

	@UiField
	Button btnCancel;

	private InputAccountFormObject object;
	
	@Override
	public void loadData() {
		Map<String,String> map = GuiUtils.getValueFromConstant(constants.stringLanguage());
		for (String key : map.keySet()) {
			lbxLanguage.addItem(map.get(key),key);
		}
		
		htmRegisterError.setMessage(constants.emptyField());
		htmDistributorCode.setHTML(object.getDistributorCode());
		htmFullName.setHTML(object.getFullName());
		if (object.getSpouseFullName() != null
				&& !object.getSpouseFullName().isEmpty()) {
			htmSpouseFullName.setHTML(object.getSpouseFullName());
			pnlSpouseFullName.setVisible(true);
		} else {
			pnlSpouseFullName.setVisible(false);
		}
	}
	
	private void bind() {
		object.setEmail(tbxEmail.getValue());
		object.setLanguage(lbxLanguage.getValue(lbxLanguage.getSelectedIndex()));
		object.setUsername(tbxUsername.getValue());
		object.setPin(tbxPassword.getValue());
		object.setRetypePin(tbxRetypePassword.getValue());
	}

	@Override
	public Widget asWidget() {
		return this;
	}

	@Override
	public HasClickHandlers getRegisterClickHandlers() {
		return btnRegister;
	}

	@Override
	public HasClickHandlers getCancelClickHandlers() {
		return btnCancel;
	}

	@Override
	public void setObject(InputAccountFormObject inputObject) {
		object = inputObject;
	}
}
